﻿
using Entity.BaseEntitys;
using EntityFrameWorkCore;
using FrameWorkCore;
using ShardingCore.Extensions.ShardingPageExtensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Repository.Repository
{
    public interface IRepository : IScopeDependency
    {

    }

    //Does not support include
    public interface IRepository<TEntity, TPrimaryKey,TDbContext> : IRepository , IScopeDependency where TEntity : class , IEntity<TPrimaryKey> where TDbContext : BaseDbContext<TDbContext>
    {

        Task<ShardingPagedResult<TEntity>> QueryByPage(int pageIndex = 1, int pageSize = 10);
        IQueryable<TEntity> GetAll();

        List<TEntity> GetAllList();
        ValueTask<List<TEntity>>  GetAllListAsync();

        List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate);

        ValueTask<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate);


        TEntity Get(TPrimaryKey id);


        ValueTask<TEntity> GetAsync(TPrimaryKey id);


        TEntity Single(Expression<Func<TEntity, bool>> predicate);


        ValueTask<TEntity> SingleAsync(Expression<Func<TEntity, bool>> predicate);


        TEntity FirstOrDefault(TPrimaryKey id);


        ValueTask<TEntity> FirstOrDefaultAsync(TPrimaryKey id);


        TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate);

        ValueTask<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate);



        TEntity Insert(TEntity entity);


        ValueTask<TEntity> InsertAsync(TEntity entity);


        TEntity Update(TEntity entity);

        ValueTask<TEntity> UpdateAsync(TEntity entity);


        void Delete(TEntity entity);

        ValueTask DeleteAsync(TEntity entity);

        void Delete(TPrimaryKey id);

        ValueTask DeleteAsync(TPrimaryKey id);

        void Delete(Expression<Func<TEntity, bool>> predicate);

        ValueTask DeleteAsync(Expression<Func<TEntity, bool>> predicate);

        int Count();

        ValueTask<int> CountAsync();

        int Count(Expression<Func<TEntity, bool>> predicate);

        ValueTask<int> CountAsync(Expression<Func<TEntity, bool>> predicate);

        long LongCount();

        ValueTask<long> LongCountAsync();

        long LongCount(Expression<Func<TEntity, bool>> predicate);

        ValueTask<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate);

        void BatchInsert(List<TEntity> entitys);

        ValueTask BatchInsertAsync(List<TEntity> entitys);

        void BatchUpdateAll(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TEntity>> updateExpression);

        void BatchUpdateColums(Expression<Func<TEntity, bool>> predicate, TEntity updateValue, List<string> updateColumns = null);

        void BatchDelete(Expression<Func<TEntity, bool>> predicate);

        ValueTask BatchUpdateAllAsync(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TEntity>> updateExpression);

        ValueTask BatchUpdateColumsAsync(Expression<Func<TEntity, bool>> predicate, TEntity updateValue, List<string> updateColumns = null);

        ValueTask BatchDeleteAsync(Expression<Func<TEntity, bool>> predicate);

    }
}
